package com.css.common.core.config;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import com.css.common.core.exception.ServiceException;
import com.css.common.core.utils.GyUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import com.alibaba.fastjson.JSONObject;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestUtil;
import feign.FeignException;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;

/**
 * @description: 银联商务OCR识别相关的feign配置
 * @Title: YlswOCRFeignConfig
 * @Author zhuowugong
 * @Package com.invoice.config
 * @Date 2024/8/17 15:37
 */
@Slf4j
public class YlswOCRFeignConfig {
    
    @Value("${ylsw.ocrAppId:}")
    private String ocrAppId;

    @Value("${ylsw.ocrAppKey:}")
    private String ocrAppKey;

    private final DateTimeFormatter dateTimeFormatter =  DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private final String signMethod = "SHA256";
    private final String getYlswOCRAccessToken = "getYlswOCRAccessToken";//获取token接口，请求头认证，请求报文加密，返回报文无需解密
    @Bean
    public RequestInterceptor interceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
            	final String method = template.methodMetadata().method().getName();
            	if (getYlswOCRAccessToken.equals(method)) {
            		if (GyUtils.isNull(ocrAppId)) {
                        throw new ServiceException("银联商务中台接口请求ocrAppId为空");
                    }
                	if (GyUtils.isNull(ocrAppKey)) {
                        throw new ServiceException("银联商务中台接口请求ocrAppKey为空");
                    }
                	 //设置请求头
                    template.header("Content-Type", "application/json;charset=utf-8");  
                    final JSONObject req = new JSONObject();
                    final String timestamp = LocalDateTime.now().format(dateTimeFormatter);
                    final String nonce = IdUtil.fastSimpleUUID();
                    //signature=SHA256_hex(appId+timestamp+nonce+appKey)sha256加密,返回64位十六进制字符串
                    final String signature = DigestUtil.sha256Hex(ocrAppId+timestamp+nonce+ocrAppKey);
                    req.put("appId", ocrAppId);
                    req.put("timestamp", timestamp);
                    req.put("nonce", nonce);
                    req.put("signMethod", signMethod);
                    req.put("signature", signature);
                    template.body(req.toString());
            	}           	
            }
        };
    }

    @Bean
    public Decoder decoder() {
        return new Decoder() {
            @Override
            public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
                final String content = IoUtil.read(response.body().asInputStream(),Charset.forName(CharsetUtil.UTF_8));
                log.info("返回报文体body:{}",content);
                final JSONObject jsonObject = JSONObject.parseObject(content);
                Object result = jsonObject.toJavaObject(type);
                return result;
            }
        };
    }

}
